package com.wzx.user.service.impl;

import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzx.common.exception.LeadNewsException;
import com.wzx.common.pojo.resp.Result;
import com.wzx.common.util.date.DateUtil;
import com.wzx.common.util.username.RandomAccountUtil;
import com.wzx.user.dto.*;
import com.wzx.user.mapper.GroupMapper;
import com.wzx.user.mapper.RelationMapper;
import com.wzx.user.mapper.UserMapper;
import com.wzx.user.mongo.*;
import com.wzx.user.pojo.Group;
import com.wzx.user.pojo.Relation;
import com.wzx.user.pojo.User;
import com.wzx.user.service.GroupService;
import com.wzx.user.vo.GroupAddAdmin;
import com.wzx.user.vo.GroupQueryUserVo;
import com.wzx.user.vo.GroupVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author wzx
 * @version 1.0
 * @date 2022/7/28 - 21:36
 * @description 标题
 */
@Service
@Transactional
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements GroupService {

    public static final String GROUP_INFO = "t_groupInfo_";
    public static final String GROUP_MSG = "t_groupMsg_";

    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RelationMapper relationMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public GroupDto createGroup(GroupVo groupVo) throws LeadNewsException {
        //1，创建账号
        Group group = new Group();
        String createTime = DateUtils.format(new Date());
        BeanUtils.copyProperties(groupVo, group);
        group.setCreateId(groupVo.getCreateId());
        group.setCreateTime(createTime);
        group.setUsername(getUsername());
        group.setGroupHead(groupVo.getGroupHead());
        group.setGroupName(groupVo.getGroupName());
        groupMapper.insert(group);

        //2，拉入群主
        Relation relation = new Relation();
        relation.setUid(group.getCreateId());
        relation.setFid(group.getGid());
        relation.setType("3");
        relation.setIdentity("1");
        //relation.setCreateTime(DateUtil.getDate());
        relationMapper.insert(relation);

        //3，拉取用户进入群聊
        if (!StringUtils.isEmpty(groupVo.getUserIds())) {
            String[] split = groupVo.getUserIds().split(",");
            for (String userId : split) {
                Relation relationUser = new Relation();
                relationUser.setUid(Integer.parseInt(userId));
                relationUser.setFid(group.getGid());
                relationUser.setType("3");
                relationUser.setIdentity("3");
                relationMapper.insert(relationUser);
            }
        }

        /*GroupInfo groupInfo = new GroupInfo();
        groupInfo.setCreateTime(createTime);
        groupInfo.setUserId(groupVo.getCreateId());
        groupInfo.setHead(groupVo.getCreateHead());
        groupInfo.setNickname(groupVo.getCreateName());
        groupInfo.setUserType("1");
        mongoTemplate.save(groupInfo, GROUP_INFO + group.getGid());*/

        //在群聊中发送一条消息
        SendMsg sendMsg = new SendMsg();
        sendMsg.setId(getId(GROUP_MSG + group.getGid()));
        sendMsg.setSenderId(groupVo.getCreateId() + "");
        sendMsg.setMessage("用户：" + groupVo.getCreateName() + "创建了群聊！");
        sendMsg.setImgUrl(groupVo.getCreateHead());
        sendMsg.setTypes(6);
        sendMsg.setTime(DateUtil.getDate());
        sendMsg.setState("0");
        sendMsg.setName(groupVo.getCreateName());
        mongoTemplate.insert(sendMsg, GROUP_MSG + group.getGid());

        GroupDto groupDto = new GroupDto();
        groupDto.setGid(group.getGid());
        groupDto.setGroupHead(group.getGroupHead());
        groupDto.setGroupName(group.getGroupName());
        return groupDto;
    }

    public long getId(String collName) {
        Query query = new Query();
        query.addCriteria(Criteria.where("collName").is(collName));
        List<SequenceId> sequenceIds = mongoTemplate.find(query, SequenceId.class);
        if (sequenceIds.isEmpty()) {
            SequenceId sequenceId = new SequenceId();
            sequenceId.setCollName(collName);
            sequenceId.setSeqId(1);
            mongoTemplate.insert(sequenceId);
            return 1;
        } else {
            long seqId = sequenceIds.get(0).getSeqId();
            long newSeqId = seqId + 1;
            Update update = Update.update("seqId", newSeqId);
            mongoTemplate.upsert(query, update, SequenceId.class);
            return newSeqId;
        }
    }

    @Override
    public GroupInfoDto getGroupInfo(Integer gid) {
        //获取家族成员
        Query query = new Query();
        query.skip(0);
        //设置查询条数
        query.limit(4);
        String conName = GROUP_INFO + gid;
        List<GroupInfo> groupInfos = mongoTemplate.find(query, GroupInfo.class, conName);
        long count = mongoTemplate.count(query, GroupInfo.class, conName);

        QueryWrapper<Group> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("gid", gid);
        Group group = groupMapper.selectOne(queryWrapper);

        GroupInfoDto groupInfoDto = new GroupInfoDto();
        groupInfoDto.setGroupInfoList(groupInfos);
        groupInfoDto.setNum(count);
        groupInfoDto.setUsername(group.getUsername());

        return groupInfoDto;
    }

    @Override
    public Result getMsgByGroup(Integer page, Integer size, Integer gid) {
        Query query = new Query();
        //总记录数
        long total = mongoTemplate.count(query, SendMsg.class, GROUP_MSG + gid);
        query.with(Sort.by(Sort.Order.desc("id")));

        //设置起始数
        query.skip((page - 1) * size);
        //设置查询条数
        query.limit(size);

        List<SendMsg> sendMsgs = mongoTemplate.find(query, SendMsg.class, GROUP_MSG + gid);

        float pagesFloat = (float) total / (float) size;
        long pages = (long) Math.ceil(pagesFloat);
        if (pages < page) {
            sendMsgs = new ArrayList<>();
        }
        Collections.reverse(sendMsgs);
        return Result.successByPage(page, size, total, pages, sendMsgs);
    }

    @Override
    public SendMsg addGroup(SystemMsg systemMsg) {
        Query query = new Query();
        query.addCriteria(Criteria.where("senderId").is(systemMsg.getSenderId())
                .and("receiverId").is(systemMsg.getReceiverId())
                .and("sysType").is(systemMsg.getSysType())
        );
        if ("1".equals(systemMsg.getState())) {
            Update update = Update.update("state", systemMsg.getState());
            mongoTemplate.upsert(query, update, SystemMsg.class);

            String createTime = DateUtil.getDate();

            Relation relation = new Relation();
            relation.setUid(systemMsg.getReceiverId());
            relation.setFid(systemMsg.getGroupId());
            //relation.setCreateTime(createTime);
            relation.setIdentity("3");
            relation.setType("3");
            relationMapper.insert(relation);

            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("userId", systemMsg.getReceiverId());
            User user = userMapper.selectOne(queryWrapper);

            /*GroupInfo groupInfo = new GroupInfo();
            groupInfo.setCreateTime(createTime);
            groupInfo.setUserId(systemMsg.getReceiveId());
            groupInfo.setHead(user.getHead());
            groupInfo.setNickname(user.getNickname());
            groupInfo.setUserType("3");
            mongoTemplate.save(groupInfo, GROUP_INFO + systemMsg.getGroupId());*/

            //在群聊中发送一条消息
            Query msgQuery = new Query();
            msgQuery.with(Sort.by(Sort.Order.desc("tip")));
            //设置起始数
            msgQuery.skip(0);
            //设置查询条数
            msgQuery.limit(1);
            List<SendMsg> sendMsgs = mongoTemplate.find(msgQuery, SendMsg.class, GROUP_MSG + systemMsg.getGroupId());
            SendMsg oldSendMsg = sendMsgs.get(0);

            //SendMsg sendMsg = new SendMsg();

            //sendMsg.setId(getId(GROUP_MSG + systemMsg.getGroupId()));
            if (null == oldSendMsg.getTip()) {
                oldSendMsg.setTip(1);
            }
            SendMsg sendMsg = new SendMsg();
            sendMsg.setTip(oldSendMsg.getTip() + 1);
            sendMsg.setSenderId(systemMsg.getReceiverId() + "");
            sendMsg.setMessage("用户：" + systemMsg.getSenderName() + "拉取用户：" + user.getNickname() + "进入群聊");
            sendMsg.setImgUrl(user.getHead());
            sendMsg.setTypes(6);
            sendMsg.setTime(DateUtil.getDate());
            sendMsg.setState("0");
            sendMsg.setName(user.getNickname());
            //mongoTemplate.insert(sendMsg, GROUP_MSG + systemMsg.getGroupId());
            return sendMsg;
        } else {
            Update update = Update.update("state", systemMsg.getState());
            mongoTemplate.upsert(query, update, SystemMsg.class);
            return new SendMsg();
        }
    }

    @Override
    public List<UserDto> getGroupFriend(Integer userId, Integer gid) {
        return userMapper.selectFriendByGroup(userId, gid);
    }

    @Override
    public void deleteGroupById(Integer groupId, Integer userId) {
        //删除管理关系
        QueryWrapper<Relation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", userId);
        queryWrapper.eq("fid", groupId);
        queryWrapper.eq("type", "3");
        relationMapper.delete(queryWrapper);

        //删除系统消息
        Query query = new Query();
        query.addCriteria(Criteria.where("receiverId").is(userId).and("groupId").is(groupId));
        mongoTemplate.remove(query, SystemMsg.class);

        /*Relation relation = relationMapper.selectOne(queryWrapper);
        if (relation.getIdentity().equals("1")){
            //普通用户退出即可
            relationMapper.delete(queryWrapper);
        }else {
            //删除所有与群聊关联的用户
            QueryWrapper<Relation> deleteQuery = new QueryWrapper<>();
            deleteQuery.eq("fid",groupId);
            deleteQuery.eq("type","3");
            relationMapper.delete(deleteQuery);
            //删除MongoDB
            mongoTemplate.dropCollection(GROUP_MSG + groupId);

        }
        return relation.getIdentity();*/
    }

    @Override
    public GroupHeadInfoDto queryGroupByHeadInfo(Integer groupId, Integer userId) throws LeadNewsException {
        Group group = groupMapper.selectById(groupId);
        if (group == null) {
            throw new LeadNewsException("群聊已解散");
        }
        QueryWrapper<Relation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", userId);
        queryWrapper.eq("fid", groupId);
        queryWrapper.eq("type", "3");
        Relation relation = relationMapper.selectOne(queryWrapper);
        if (relation == null) {
            throw new LeadNewsException("未建立关系");
        }

        GroupHeadInfoDto groupHeadInfoDto = new GroupHeadInfoDto();
        groupHeadInfoDto.setUserId(userId);
        groupHeadInfoDto.setGroupId(groupId);
        groupHeadInfoDto.setGroupName(group.getGroupName());
        groupHeadInfoDto.setGroupHead(group.getGroupHead());
        groupHeadInfoDto.setDescribe(group.getGroupDescribe());
        groupHeadInfoDto.setIdentity(relation.getIdentity());
        groupHeadInfoDto.setEstoppel(group.getEstoppel());
        groupHeadInfoDto.setProtect(group.getProtect());
        groupHeadInfoDto.setInviteType(group.getInviteType());
        //如果昵称为空，查询用户昵称
        if (StringUtils.isEmpty(relation.getIInGroupRemarks())) {
            User user = userMapper.selectById(userId);
            groupHeadInfoDto.setIInGroupRemarks(user.getNickname());
        } else {
            groupHeadInfoDto.setIInGroupRemarks(relation.getIInGroupRemarks());
        }


        return groupHeadInfoDto;
    }

    @Override
    public void updateGroupByHeadInfo(GroupHeadInfoDto groupHeadInfoDto) throws LeadNewsException {
        if (groupHeadInfoDto.getIdentity().equals("3")) {
            throw new LeadNewsException("您没有权限修改该头像！");
        }
        //查询唯一的群聊信息
        Group group = groupMapper.selectById(groupHeadInfoDto.getGroupId());

        //修改
        group.setGroupHead(groupHeadInfoDto.getGroupHead());
        group.setGroupName(groupHeadInfoDto.getGroupName());
        group.setGroupDescribe(groupHeadInfoDto.getDescribe());

        groupMapper.updateById(group);
    }

    @Override
    public List<GroupUserDto> queryGroupUsers(GroupQueryUserVo groupQueryUserVo) {
        return groupMapper.queryGroupUsers(groupQueryUserVo);
    }

    @Override
    public Group queryGroupInfo(Integer groupId) {
        return groupMapper.selectById(groupId);
    }

    @Override
    public void changeGroupState(GroupInfoStateDto groupInfoStateDto) {
        groupMapper.changeGroupState(groupInfoStateDto);
    }

    @Override
    public void changeUsersAdmin(GroupAddAdmin groupAddAdmin) {
        relationMapper.changeUsersAdmin(groupAddAdmin);
    }

    @Override
    public void deleteGroupByIds(Integer groupId, Integer[] userIds) {
        relationMapper.deleteByIds(groupId, userIds);
    }

    @Override
    public void dissolutionGroup(Integer groupId) {
        //1，群聊数据
        groupMapper.deleteById(groupId);
        //2，删除所有关联关系
        QueryWrapper<Relation> queryWrapper = new QueryWrapper<Relation>();
        queryWrapper.eq("fid", groupId);
        queryWrapper.eq("type", "3");
        relationMapper.delete(queryWrapper);
    }

    @Override
    public List<Group> queryGroupByUser(Integer userId) {
        //查询用户加入了哪些群聊
        /*List<Group> groups = relationMapper.selectAddGroupList(userId);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userId", userOne.getUserId());
        resultMap.put("nickname", userOne.getNickname());
        resultMap.put("head", userOne.getHead());

        resultMap.put("groupList", groups);
        */
        return null;
    }

    public String getUsername() throws LeadNewsException {
        while (true) {
            String accountNumber = RandomAccountUtil.randomNumberIsTen(9, 1).toString();
            QueryWrapper<Group> queryWrapperByUsername = new QueryWrapper<>();
            queryWrapperByUsername.eq("username", accountNumber);
            Integer count = groupMapper.selectCount(queryWrapperByUsername);
            if (count == 0) {
                return accountNumber;
            }
        }
    }
}
